package com.ssyx.cart.service.Impl;

import com.alibaba.fastjson.JSON;
import com.ssyx.cart.feign.ProductFeignClient;
import com.ssyx.cart.service.CartInfoService;
import com.ssyx.common.auth.AuthContextHolder;
import com.ssyx.common.exception.SsyxException;
import com.ssyx.common.result.Result;
import com.ssyx.common.result.ResultCodeEnum;
import com.ssyx.enums.SkuType;
import com.ssyx.model.order.CartInfo;
import com.ssyx.model.product.SkuInfo;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * ClassName:CartServiceImpl
 * Description:
 *
 * @Author kay
 * @Create 2024/5/19 16:27
 * @Version 1.0
 */
@Service
public class CartInfoServiceImpl implements CartInfoService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private ProductFeignClient productFeignClient;
    //添加商品到购物车
    @Override
    public void addToCart(Long userId, Long skuId, Integer skuNum) {

        //构建hash类型key名称
        String cartKey = "user:cart:"+userId;

        //1.从redis中获取用户购物车对象cartInfoObj(使用key和field)
        //hash类型 key:user:cart:"+userId  field:skuId  value:sku信息CartInfo
        //从redis里面获取购物车数据,根据用户id+skuId获取(hash类型key+field)
        Object cartInfoObj =
                redisTemplate.opsForHash()
                        .get(cartKey, String.valueOf(skuId));

        //2.如果购物车存在添加商品,把商品数量相加
        CartInfo cartInfo = null;
        if(cartInfoObj != null){ //从redis中获得的对象不为空,则购物车已经有该商品
            //cartInfoObj -->CartInfo
            cartInfo = JSON.parseObject(cartInfoObj.toString(),CartInfo.class);
            //更新数量及其他属性
            int currentSkuNum = cartInfo.getSkuNum() + skuNum;
            if(currentSkuNum < 1){
                return ;
            }
            //大于限购个数，不能更新个数
            if(currentSkuNum >= cartInfo.getPerLimit()) {
                throw new SsyxException(ResultCodeEnum.SKU_LIMIT_ERROR);
            }
            cartInfo.setSkuNum(currentSkuNum);
            cartInfo.setIsChecked(1);
            cartInfo.setUpdateTime(new Date());
        }else{
            //3.如果购物车没有添加商品,直接把该商品添加到购物车(添加到redis中)
            //第一次添加只能添加一个
            skuNum = 1;

            cartInfo = new CartInfo();
            SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId);
            if(null == skuInfo) {
                throw new SsyxException(ResultCodeEnum.DATA_ERROR);
            }
            //设置相关数据到cartInfo对象中 skuInfo -> cartInfo
            cartInfo.setSkuId(skuId);
            cartInfo.setCategoryId(skuInfo.getCategoryId());
            cartInfo.setSkuType(skuInfo.getSkuType());
            cartInfo.setIsNewPerson(skuInfo.getIsNewPerson());
            cartInfo.setUserId(userId);
            cartInfo.setCartPrice(skuInfo.getPrice());
            cartInfo.setSkuNum(skuNum);
            cartInfo.setCurrentBuyNum(skuNum);
            cartInfo.setSkuType(SkuType.COMMON.getCode());
            cartInfo.setPerLimit(skuInfo.getPerLimit());
            cartInfo.setImgUrl(skuInfo.getImgUrl());
            cartInfo.setSkuName(skuInfo.getSkuName());
            cartInfo.setWareId(skuInfo.getWareId());
            cartInfo.setIsChecked(1);
            cartInfo.setStatus(1);
            cartInfo.setCreateTime(new Date());
            cartInfo.setUpdateTime(new Date());
        }
        //4.添加到redis中
        redisTemplate.opsForHash().put(cartKey,String.valueOf(skuId),
                JSON.toJSONString(cartInfo));
        //设置过期时间
        redisTemplate.expire(cartKey,7, TimeUnit.DAYS);
    }

    //根据skuId,删除购物车中对应的商品sku
    @Override
    public void deleteSkuInCart(Long skuId, Long userId) {
        String cartKey = "user:cart:"+userId;
        redisTemplate.opsForHash().delete(cartKey,String.valueOf(skuId));
    }

    //清空购物车
    @Override
    public void deleteAllCart(Long userId) {
        String cartKey = "user:cart:"+userId;
        redisTemplate.delete(cartKey);
    }

    //批量删除购物车商品
    @Override
    public void batchDeleteCart(List<Long> skuIdList, Long userId) {
        String cartKey = "user:cart:"+userId;
        for(Long skuId : skuIdList){
            redisTemplate.opsForHash().delete(cartKey,String.valueOf(skuId));
        }
    }

    //购物车列表
    @Override
    public List<CartInfo> getCartList(Long userId) {
        List<CartInfo> cartInfoList = new ArrayList<>();
        if (StringUtils.isEmpty(userId)) {
            cartInfoList = null;
        }

        String cartKey = "user:cart:"+userId;
        //根据key从redis中hash类型获取所有的value值 cartInfo
        List<Object> valueList = redisTemplate.opsForHash().values(cartKey);

        //List<Object> -> List<CartInfo>
        if(!CollectionUtils.isEmpty(valueList)){
            cartInfoList = valueList.stream().map(cartInfoObj ->
                            JSON.parseObject(cartInfoObj.toString(),CartInfo.class))
                    .sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime())) //购物车商品,按加入购物车的时间排序
                    .collect(Collectors.toList());
        }
        return cartInfoList;
    }

    //更新购物车单个商品项的选中状态
    @Override
    public void checkCart(Long userId, Integer isChecked, Long skuId) {
        String cartKey = "user:cart:"+userId;
        //判断key是否包含field
        Boolean hasKey = redisTemplate.opsForHash().hasKey(cartKey, String.valueOf(skuId));

        if(hasKey){
            //根据key+field把value取出来
            Object cartInfoObj = redisTemplate.opsForHash().get(cartKey, String.valueOf(skuId));
            CartInfo cartInfo = JSON.parseObject(cartInfoObj.toString(), CartInfo.class);
            //更新value里面的选中状态
            cartInfo.setIsChecked(isChecked);

            //放回到redis的hash类型中
            redisTemplate.opsForHash().put(cartKey,String.valueOf(skuId),
                    JSON.toJSONString(cartInfo));

            //设置过期时间
            redisTemplate.expire(cartKey,7, TimeUnit.DAYS);
        }
    }

    //更新购物车全选状态
    @Override
    public void checkAllCart(Long userId, Integer isChecked) {
        String cartKey = "user:cart:"+userId;
        //根据key从redis中hash类型获取所有的value值 cartInfo
        List<Object> valueList = redisTemplate.opsForHash().values(cartKey);

        //List<Object> -> List<CartInfo>
        if(!CollectionUtils.isEmpty(valueList)){
            List<CartInfo> cartInfoList = valueList.stream().map(cartInfoObj ->
                            JSON.parseObject(cartInfoObj.toString(),CartInfo.class))
                    .collect(Collectors.toList());
            //把每个商品isChecked进行更新
            cartInfoList.forEach(cartInfo ->{
                cartInfo.setIsChecked(isChecked);
                redisTemplate.opsForHash().put(cartKey,String.valueOf(cartInfo.getSkuId()),
                        JSON.toJSONString(cartInfo));
            });
        }
        //设置过期时间
        redisTemplate.expire(cartKey,7, TimeUnit.DAYS);
    }

    //修改购物车中批量商品项的选中状态
    @Override
    public void batchCheckCart(List<Long> skuIdList, Long userId, Integer isChecked) {
        String cartKey = "user:cart:"+userId;
        skuIdList.forEach(skuId -> {
            //根据key+field把value取出来
            Object cartInfoObj = redisTemplate.opsForHash().get(cartKey, String.valueOf(skuId));
            CartInfo cartInfo = JSON.parseObject(cartInfoObj.toString(), CartInfo.class);
            //更新value里面的选中状态
            cartInfo.setIsChecked(isChecked);
            //放回到redis的hash类型中
            redisTemplate.opsForHash().put(cartKey,String.valueOf(skuId),
                    JSON.toJSONString(cartInfo));
        });

        //设置过期时间
        redisTemplate.expire(cartKey,7, TimeUnit.DAYS);
    }

    //根据用户id得到,购物车中被选中的商品项列表
    @Override
    public List<CartInfo> getCartCheckedList(Long userId) {
        String cartKey = "user:cart:"+userId;
        //根据key从redis中hash类型获取所有的value值 cartInfo
        List<Object> valueList = redisTemplate.opsForHash().values(cartKey);
        //List<Object> -> List<CartInfo>
        List<CartInfo> cartInfoList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(valueList)) {
            cartInfoList = valueList.stream().map(cartInfoObj ->
                            JSON.parseObject(cartInfoObj.toString(), CartInfo.class))
                    .collect(Collectors.toList());
        }
        //筛选出被选中的商品项
        List<CartInfo> CartCheckedList = cartInfoList.stream().
                filter(CartInfo ->CartInfo.getIsChecked() == 1)
                .collect(Collectors.toList());
        return CartCheckedList;
    }

    //删除购物车中,被选中的商品
    @Override
    public Boolean removeCartChecked() {
        Long userId = AuthContextHolder.getUserLoginVo().getUserId();
        String cartKey = "user:cart:"+userId;
        List<Object> objectList = redisTemplate.opsForHash().values(cartKey);       // redis中要删除选中的购物项数据
        if(!CollectionUtils.isEmpty(objectList)) {
            objectList.stream().map(cartInfoJSON -> JSON.parseObject(cartInfoJSON.toString(), CartInfo.class))
                    .filter(cartInfo -> cartInfo.getIsChecked() == 1)
                    .forEach(cartInfo -> redisTemplate.opsForHash().delete(cartKey , String.valueOf(cartInfo.getSkuId())));
        }
        return true;
    }


}
